<html>

<head>
    <title>017 | Scene management | J3D</title>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

    <link rel="stylesheet" href="common/common.css"/>
    <script type="text/javascript" src="common/common.js"></script>

    <script type="text/javascript" src="../build/j3d.js"></script>
    <script type="text/javascript" src="js/Persistence.js"></script>

    <script id="blendFilter" type="x-shader/x-filter">
        //#name BlendFilter
        //#author bartekd

        //#include CommonFilterInclude

        //#vertex
        //#include BasicFilterVertex

        //#fragment
        uniform sampler2D uNewTexture;
        uniform sampler2D uOldTexture;

        varying vec2 vTextureCoord;

        void main(void) {
            vec4 n = texture2D(uNewTexture, vTextureCoord);
            vec2 c = vec2(0.5, 0.5) - vTextureCoord;
            vec4 o = texture2D(uOldTexture, vTextureCoord + c * 0.01);
            //o = vec4(mix(n.rgb, o.rgb, 0.99), 1.0);
            gl_FragColor = vec4(mix(n.rgb, o.rgb, 0.96), 1.0);
        }
    </script>

    <script>

        var engine, cubemesh, sceneCubeMat, childCubeMat, sun, camera, camroot, post;
        var cubes;
        var mx = 0, my = 0;
        var usepost = false;

        function init() {
            if (!checkWebGL()) return;

            engine = new J3D.Engine();
            engine.setClearColor(J3D.Color.white);

            sceneCubeMat = J3D.BuiltinShaders.fetch("Gouraud");
            sceneCubeMat.colorTexture = getTexture("#00b125", "#0b6001");
            sceneCubeMat.hasColorTexture = true;

            childCubeMat = J3D.BuiltinShaders.fetch("Gouraud");
            childCubeMat.colorTexture = getTexture("#ff4600", "#ff9200");
            childCubeMat.hasColorTexture = true;

            ambient = new J3D.Transform();
            ambient.light = new J3D.Light(J3D.AMBIENT);
            ambient.light.color = new J3D.Color(0.75, 0.75, 0.75, 1);

            cubemesh = J3D.Primitive.Cube(0.5, 0.5, 0.5);

            cubes = [];

            sun = new J3D.Transform();
            sun.light = new J3D.Light(J3D.DIRECT);
            sun.light.color = new J3D.Color(0.75, 0.75, 0.75, 1);
            sun.rotation.y = Math.PI / 2;

            camera = new J3D.Transform();
            camera.camera = new J3D.Camera({ fov:30 });
            camera.position.z = 12;
            engine.camera = camera;

            camroot = new J3D.Transform();
            camroot.add(camera, sun);

            post = new J3D.Persistence(engine);
		    post.blendFilter = new J3D.ShaderUtil.parseGLSL(document.getElementById("blendFilter").firstChild.nodeValue);

            populateScene();

            document.onmousemove = function(e) {
                mx = ( e.clientX / window.innerWidth  ) * 2 - 1;
                my = ( e.clientY / window.innerHeight ) * 2 - 1;
            }

            document.onkeydown = function(e) {
                switch (e.keyCode) {
                    case 65: // A
                        addCube();
                        break;
                    case 83: // S
                        addCube(cubes[ 0 ]);
                        break;
                    case 82: // R
                        if (cubes.length > 1) removeCube();
                        break;
                    case 81: // Q
                        engine.scene.removeAll();
                        cubes = [];
                        populateScene();
                        break;
                    case 80: // P
                        usepost = !usepost;
                        break;
                    default:
                        console.log(e.keyCode);
                }

                updateDesc("<u>A</u> or <u>S</u> to add cube. <u>R</u> to remove, <u>Q</u> to remove all.<br><u>P</u> to toggle post effect. Cubes on screen: " + cubes.length);
                camera.position.z = 12 + cubes.length * 0.03;
            }

            draw();
        }

        function populateScene() {
            engine.scene.add(camroot, ambient);
            addCube(null, 0, 0);
        }

        function getTexture(ca, cb) {
            var c = document.createElement("canvas");
            c.width = 256;
            c.height = 256;
            var ctx = c.getContext("2d");

            ctx.fillStyle = ca;
            ctx.fillRect(0, 0, 128, 128);
            ctx.fillRect(128, 128, 128, 128);

            ctx.fillStyle = cb;
            ctx.fillRect(128, 0, 128, 128);
            ctx.fillRect(0, 128, 128, 128);

            return new J3D.Texture(c);
        }

        function addCube(parent, s) {
            var addToRoot = parent == null;

            parent = parent || engine.scene;
            s = (s == null) ? 4 : s;

            var c = new J3D.Transform();
            c.position = v3.random().norm().mul(s);

            c.rotation.x = Math.PI * 2 * Math.random();
            c.rotation.x = Math.PI * 2 * Math.random();

            c.renderer = (addToRoot) ? sceneCubeMat : childCubeMat;
            c.geometry = cubemesh;

            c.rotXspeed = 0.1 + Math.random() * 0.25;
            c.rotYspeed = 0.1 + Math.random() * 0.25;

            cubes.push(c);
            parent.add(c);


        }

        function removeCube() {
            engine.scene.remove(cubes.pop(), true); // 2nd argument = recursive removal
        }

        function draw() {
            requestAnimationFrame(draw);

            var dsec = J3D.Time.deltaTime / 1000;

            camroot.rotation.y += dsec * 0.5;
            for (var i = 0; i < cubes.length; i++) {
                var c = cubes[i];
                c.rotation.x += dsec * c.rotXspeed;
                c.rotation.y += dsec * c.rotYspeed;
            }


            if(usepost) post.render();
            else engine.render();
        }

    </script>

</head>

<body onload="init();">

<script>
    setLabels("017. Scene management", "<u>A</u> or <u>S</u> to add cube. <u>R</u> to remove, <u>Q</u> to remove all.<br><u>P</u> to toggle post effect. Cubes on screen: 1");
</script>

<script type="text/javascript">

    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-24294554-1']);
    _gaq.push(['_trackPageview']);

    (function() {
        var ga = document.createElement('script');
        ga.type = 'text/javascript';
        ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga, s);
    })();

</script>

</body>

</html>












